package com.practice.references;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.LinkedList;

/**
 * 弱引用:
 * 1. 弱引用与软引用类似
 * 2. 弱引用比软引用的生命周期更短
 * 3. 垃圾收集器扫描标记时，一旦发现只具有弱引用的对象，不管当前堆空间是否足够都会回收
 * 4.
 */
public class WeakReferenceTest {
    public static void main(String[] args) {
        String a = "abc";
        WeakReference<String> weakReference = new WeakReference<>(a);
        System.out.println(weakReference.get());
        System.gc();
        System.out.println(weakReference.get());
        a = null;
        System.gc();
        System.out.println(weakReference.get());
    }
}

class GCTarget {
    public String id;
    byte[] buffer = new byte[1024];

    public GCTarget(String id) {
        this.id = id;
    }

    @Override
    protected void finalize() {
        System.out.println("Finalizing GCTarget, id is: " + id);
    }
}

class GCTargetWeakReference extends WeakReference<GCTarget> {
    public String id;

    public GCTargetWeakReference(GCTarget referent, ReferenceQueue<? super GCTarget> queue) {
        super(referent, queue);
        this.id = referent.id;
    }

    @Override
    protected void finalize() {
        System.out.println("Finalizing GCTargetWeakReference " + id);
    }
}

class WeakReferenceTest2 {
    private final static ReferenceQueue<GCTarget> REFERENCE_QUEUE = new ReferenceQueue<>();

    public static void main(String[] args) {
        LinkedList<GCTargetWeakReference> gcTargetList = new LinkedList<>();
        for (int i = 0; i < 5; i++) {
            GCTarget gcTarget = new GCTarget(String.valueOf(i));
            GCTargetWeakReference weakReference = new GCTargetWeakReference(gcTarget, REFERENCE_QUEUE);
            gcTargetList.add(weakReference);
            System.out.println("Just created GCTargetWeakReference obj: " + gcTargetList.getLast());
        }

        System.gc();

//        try {
//            Thread.sleep(6000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }

        Reference<? extends GCTarget> reference;
        while ((reference = REFERENCE_QUEUE.poll()) != null) {
            if (reference instanceof GCTargetWeakReference) {
                System.out.println("In queue, id is: " + ((GCTargetWeakReference) (reference)).id);
            }
        }
    }
}